package com.jokerpan.project.util;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.security.GeneralSecurityException;
import java.util.concurrent.TimeUnit;

/**
 * HttpClient连接池<br/>
 */
public class GlobalHttpClientConnectionManager {
    /**
     * 设置访问协议
     */
    private PoolingHttpClientConnectionManager connMrg = null;
    /**
     * 超时参数
     */
    private long timeToLive = 10;
    /**
     * 超时参数单位
     */
    private TimeUnit tunit = TimeUnit.SECONDS;
    /**
     * 设置整个连接池最大连接数
     */
    private int maxTotal = 256;
    /**
     * 单个路由最大连接数
     */
    private int defaultMaxPerRoute = 64;

    /**
     * 初始化
     */
    public GlobalHttpClientConnectionManager() {
        connMrg = new PoolingHttpClientConnectionManager(timeToLive, tunit);
        connMrg.setMaxTotal(maxTotal);
        connMrg.setDefaultMaxPerRoute(defaultMaxPerRoute);
    }

    /**
     * 初始化
     * @param timeToLive         超时参数
     * @param tunit              超时单位
     * @param maxTotal           连接池最大连接数
     * @param defaultMaxPerRoute 主机对MaxTotal的一个细分，比如：MaxtTotal=256
     *                           efaultMaxPerRoute=64，而我只连接到http://www.baidu.com时，
     *                           到这个主机的并发最多只有64而不是128
     */
    public GlobalHttpClientConnectionManager(long timeToLive, TimeUnit tunit, int maxTotal, int defaultMaxPerRoute) {
        this.timeToLive = timeToLive;
        this.tunit = tunit;
        this.maxTotal = maxTotal;
        this.defaultMaxPerRoute = defaultMaxPerRoute;
    }

    public PoolingHttpClientConnectionManager getManager() {
        return connMrg;
    }

    public CloseableHttpClient getHttpClient() {
        return HttpClients.custom().setConnectionManager(connMrg).build();
    }

    /**
     * 获取忽略证书的HttpClient
     */
    public CloseableHttpClient getHttpsClient() {
        return getHttpsClient(createSSLConnSocketFactory());
    }

    public CloseableHttpClient getHttpsClient(SSLConnectionSocketFactory sslSocketFactory) {
        return HttpClients.custom().setSSLSocketFactory(sslSocketFactory).setConnectionManager(connMrg).build();
    }

    /**
     * 创建SSL安全连接
     */
    private SSLConnectionSocketFactory createSSLConnSocketFactory() {
        SSLConnectionSocketFactory sslsf = null;
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> {
                // 信任所有
                return true;
            }).build();
            sslsf = new SSLConnectionSocketFactory(sslContext);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return sslsf;
    }
}